package controller.commands;

import controller.PrototypeFactory;
import core.BoxNode;
import java.util.ArrayList;
import model.graphic.locations.Location;
import model.graphic.objects.GBoxNode;
import model.graphic.objects.GNode;
import model.graphic.objects.GResizeHandle;
import model.graphic.objects.Graphical;

/**
 *
 * @author Jelle, modified by Ben
 */
public class CloneCommand extends BasicCommand {

    private GBoxNode gbn;
    private BoxNode bn;
    private Location location;
    private boolean locationSet = false;
    private String gboxID;
    private String cboxID;

    public CloneCommand(String gbn, String cbn) {
        gboxID = gbn;
        cboxID = cbn;
    }

    @Override
    public void execute() {
        gbn = controller.getPalette().getGBoxNode(gboxID);
        bn = controller.getPalette().getCBoxNode(cboxID);

        GBoxNode gnClone = null;
        BoxNode nClone = null;

        PrototypeFactory pf = new PrototypeFactory(location, gbn, bn);
        gnClone = pf.getGClone();
        nClone = pf.getCClone();

        gview.notifyObservers(new MacroCommand(pf.getCommands()));
        gmodel.setSelected(gnClone);
        gmodel.setModelChanged();
        gmodel.addObject(gnClone);


        cmodel.addObject(nClone);
        sync.put(gnClone, nClone);
        ArrayList<BasicCommand> commands = new ArrayList<BasicCommand>();
        /*for (Graphical g : gbn.getTransmitterObjects()) {
            if (GTransmitterNode.class.isAssignableFrom(g.getClass())) {
                GTransmitterNode tn = (GTransmitterNode) g;
                if (tn.getBase().equals(gbn)) {
                    if (tn.getType().equals(cons.getTriggerTransmitterInString())) {
                        commands.add(new AddTransmitterCommand(cons.getTriggerTransmitterInString(), g.getName()));
                    } else if (tn.getType().equals(cons.getTriggerTransmitterOutString())) {
                        commands.add(new AddTransmitterCommand(cons.getTriggerTransmitterOutString(), g.getName()));
                    } else if (tn.getType().equals(cons.getValueTransmitterInString())) {
                        commands.add(new AddTransmitterCommand(cons.getValueTransmitterInString(), g.getName(), tn.getClassDef()));
                    } else if (tn.getType().equals(cons.getValueTransmitterOutString())) {
                        commands.add(new AddTransmitterCommand(cons.getValueTransmitterOutString(), g.getName(), tn.getClassDef()));
                    }
                }
            }
        }*/
        GResizeHandle gr = new GResizeHandle(gnClone, 50);
        gnClone.setResizer(gr);
        gmodel.addObject(gr);
        gview.add(gr);
        gmodel.setSelected(gnClone);

        commands.add(new RedrawCommand(gnClone));
        gview.notifyObservers(new MacroCommand(commands));
        gview.add(gnClone, 1000);


        for (Graphical g : gnClone.getInternalObjects()) {
            gview.add(g, 1);
        }


        for(int i = 0; i < 2; i++){//iteration is really needed to have each item good positioned
            for (Graphical g : gnClone.getInternalObjects()) {
                if (GNode.class.isAssignableFrom(g.getClass())) {
                    GNode gn = (GNode) g;
                    gview.notifyObservers(new RedrawCommand(gn));
                }
            }
        }

    }

    /**
     * @return the location
     */
    public Location getLocation() {
        return location;
    }

    /**
     * @param location the location to set
     */
    public void setLocation(Location location) {
        this.location = location;
        this.locationSet = true;
    }

    /**
     * @return the boxnodeString
     */
    public String getGBoxID() {
        return gboxID;
    }

    /**
     * @return the boxnodeString
     */
    public String getCBoxID() {
        return cboxID;
    }
}
